home *** CD-ROM | disk | FTP | other *** search
/ Light ROM Gold / Light ROM Gold.iso / arexx / movscene.lwm < prev    next >
Text File  |  1995-05-01  |  20KB  |  693 lines

  1. /* CMD:  Move Scene v3.0
  2.  * Move Lightwave Scene file and all that it is used in it, to a new
  3.  * place.  Useful for transfering scenes to another computer.
  4.  * It will move all of your images, rearrange your scene file so
  5.  * that the objects will load from the new directory you specified.
  6.  * It will also take into account if you are moving your scenes into
  7.  * 3.5" disks and measure how much space is left, requesting new
  8.  * disks and initialize them in Amiga or IBM format.
  9.  *
  10.  * To run the macro, you will need these Workbench programs in C:
  11.  * copy, makedir, list, delete, format and rename.
  12.  *
  13.  * To use PC disks, you should have CrossDos (included in WB 2.1+) and
  14.  * installed for your internal drive (DF0).
  15.  *
  16.  * If using lha, you should have lha - if you prefer another lha
  17.  * compressor, just use your favorite editor to change "LHA" to
  18.  * the compressor you like.
  19.  * You could probably modify LHA to work with ARJ, or other PC compressor.
  20.  *
  21.  * If using compress, you should also have compress.b16 in C:.
  22.  *
  23.  * NOTE: This version 3.0 is still beta.  The reason I decided to
  24.  *       release it was that many people seemed to need it.
  25.  *       In this version, if you use any type of compression, you
  26.  *       will not be able to load the file into LW later.  You will
  27.  *       have to rename all the files.  This might be fixed later.
  28.  *       Also, if you have two different objects that start with the
  29.  *       same 8 characters, the macro will not detect this, and consider
  30.  *       you are always talking about the same object.  This will also
  31.  *       be fixed in the final version (These two things require some
  32.  *       good rewritting of the code, so you'll have to wait).
  33.  *       Bugs, comments and suggestions to ggarramuno@sicoar1.satlink.net
  34.  *
  35.  * 8/94 Version 1.0  - By Gonzalo Garramuno (C) 1994
  36.  * 11/94 Version 2.0 - By Gonzalo Garramuno (C) 1994
  37.  *                     > fixed bug with objects bigger than 65,535 bytes.
  38.  *                     > added option to turn off copying image and 
  39.  *                       image sequences.
  40.  *                     > added option for changing the paths of the
  41.  *                       scene and object files to point to the new
  42.  *                       place.
  43.  *                     > added option for multiple disks, formatting
  44.  *                       them as needed.
  45.  *                     > added lha compression if lha is in C:
  46.  *                       note: if using lha, avoid files with bad
  47.  *                             names (ie. those that have wildcards
  48.  *                             characters in them, such as ?,#,),etc)
  49.  *
  50.  * 3/95 Version 3.0 beta  (C) 1995 Gonzalo Garramuno
  51.  *                   > added shortening files to 8 characters and
  52.  *                     changing spaces to underscores.
  53.  *                   > added compress compression for SGI compatibility.
  54.  *                     watch out for wrong characters: !, etc.
  55.  */
  56.  
  57. call addlib "LWModelerARexx.port", 0
  58. call addlib "rexxsupport.library", 0, -30, 0
  59. signal on error
  60. signal on syntax
  61.  
  62. sysnam = 'Move Scene'
  63. version = 'Move Scene v3.0'
  64. statfil="T:move.scene"
  65. image = 3
  66. path = 1
  67. disk = 1
  68. dnum = 1
  69. comp = 0
  70. short = 0
  71. repl = 0
  72.  
  73. cant = 0
  74. nfil = 0
  75.  
  76. if (exists(statfil)) then do
  77.     if (~open(state, statfil, 'R')) then break
  78.     if (readln(state) ~= version) then break
  79.     l1 = readln(state)
  80.     l2 = readln(state)
  81.     image = readln(state)
  82.     path = readln(state)
  83.     disk = readln(state)
  84.     comp = readln(state)
  85.     short = readln(state)
  86.     repl = readln(state)
  87.     call close state
  88. end
  89.  
  90. if l1="L1" then do
  91. /* If you have Lightwave installed somewhere else other than
  92.    Toaster: then change the path below */
  93.     l1="Toaster:3D/Scenes"
  94.     name1=""
  95.     l2="ram:"
  96.     name2=""
  97. end
  98. else do
  99.     filenam="/"
  100.     s=2
  101.     if lastpos("/",l1)=0 then do
  102.         filenam=":"
  103.         s=1
  104.     end
  105.     name1=right(l1,length(l1)-lastpos(filenam,l1))
  106.     l1=left(l1,pos(name1,l1)-s)
  107.     
  108.     filenam="/"
  109.     s=2
  110.     if lastpos("/",l2)=0 then do
  111.         filenam=":"
  112.         s=1
  113.     end
  114.     if length(l2)=lastpos(filenam,l2) then filenam=""
  115.     name2=right(l2,length(l2)-lastpos(filenam,l2))
  116.     l2=left(l2,pos(name2,l2)-s)
  117. end
  118.  
  119. filenam=getfilename("-- Lightwave Scene --",l1,name1)
  120. if filenam ="(none)" then exit
  121.  
  122. call REQ_BEGIN("Move Scene")
  123.       id_disk=REQ_ADDCONTROL("Copy to?",'CH',"Directory",
  124.                            "Multiple"d2c(160)"DF0: Multiple"d2c(160)"PC0:")
  125.       id_image=REQ_ADDCONTROL("Copy Images?",'CH',"No Images"d2c(160)"only
  126.                               Images"d2c(160)"and"d2c(160)"Sequences")
  127.       id_path=REQ_ADDCONTROL("Change Paths",'B')
  128.  
  129.       id_comp=REQ_ADDCONTROL("Compression",'CH',"None LHA Compress")
  130.       id_short=REQ_ADDCONTROL("Shorten filenames to 8 chrs?",'B')
  131.       id_repl=REQ_ADDCONTROL("Change spaces to underscores?",'B')
  132.  
  133.       call REQ_SETVAL(id_disk,disk)
  134.       call REQ_SETVAL(id_image,image)
  135.       call REQ_SETVAL(id_path,path)
  136.       call REQ_SETVAL(id_comp,comp)
  137.       call REQ_SETVAL(id_short,short)
  138.       call REQ_SETVAL(id_repl,repl)
  139.  
  140. ok=REQ_POST()
  141.  
  142. If ok~=1 Then exit
  143.  
  144. disk = REQ_GETVAL(id_disk)
  145. image = REQ_GETVAL(id_image)
  146. path = REQ_GETVAL(id_path)
  147. comp = REQ_GETVAL(id_comp)
  148. short = REQ_GETVAL(id_short)
  149. repl = REQ_GETVAL(id_repl)
  150.  
  151. select
  152.     when disk=1 then do
  153.         Drawer=getfilename("-- Drawer to Create --",l2,name2)
  154.         if Drawer ="(none)" then exit
  155.         Drawer = short(Drawer,"")
  156.     end
  157.     when disk=2 then Drawer="DF0:"
  158.     otherwise Drawer="PC0:"
  159. end
  160.  
  161. /* Save preferences just in case */
  162. if (open(state, statfil, 'W')) then do
  163.     call writeln state, version
  164.     call writeln state, filenam
  165.     call writeln state, Drawer
  166.     call writeln state, image
  167.     call writeln state, path
  168.     call writeln state, disk
  169.     call writeln state, comp
  170.     call writeln state, short
  171.     call writeln state, repl
  172.     call close state
  173. end
  174.  
  175. if disk>1 then call askdisk()
  176.  
  177. if comp = 2 then Drawer = Drawer || ".lha"
  178. if comp = 3 then Drawer = Drawer || ".Z"
  179.  
  180. /* Number of Images in Scene and/or Objects */
  181. img=0
  182.  
  183. if (exists(filenam)) then do
  184.  
  185. /* Erase if there was a previous one by mistake */
  186.     address command
  187.     if (disk=1)&(exists(Drawer)) then do
  188.         if notify(2,"Delete "||Drawer"?")=0 then exit
  189.         'delete "'Drawer'" all  >NIL:'
  190.     end
  191.  
  192.     obj=0
  193.     if (~open(state, filenam, 'R')) then exit
  194.     parse value readln(state) with type .
  195.     if type~="LWSC" then do
  196.         Bummer("Not a Lightwave ASCII Scene!")
  197.     end
  198.     else do while eof(state)=0
  199.         type=readln(state)
  200.         if left(type,11)="LoadObject " then do
  201.         obj=obj+1
  202.             object.obj = substr(type,12)
  203.                 newobj.obj = short(object.obj,"OBJ")
  204.         end
  205.  
  206. /* Handle images in scene file
  207.  * Background, Foreground, Alpha, Displacement and Clip maps */
  208.         if image > 1 then do
  209.             l=pos(" ",type)
  210.             if l=0 then l=1
  211.             if (left(type,l)="BGImage "),
  212.               |(left(type,l)="FGImage "),
  213.               |(left(type,l)="FGAlphaImage "),
  214.               |(left(type,l)="TextureImage ") then do
  215.                 img = img + 1
  216.                    image.img = substr(type,l+1)
  217.                 newimg.img = short(image.img,"")
  218.             end
  219.         end
  220.     end
  221.     call close state
  222.  
  223. /* Make dir and copy scene file to it */
  224.     if disk=1 then call makdir(Drawer)
  225.     say "Okay, " disk
  226.     newnam = short(filenam,"LSC")
  227.     call cop(filenam,Drawer,newnam)
  228.  
  229.     if disk=1 then Drawer=Drawer||"/"
  230.  
  231. /*****************************************/
  232. /* Copy all objects to Objects Directory */
  233. /*****************************************/
  234.  
  235.     if obj>0 then do
  236.         call METER_BEGIN(obj+1,"Moving Objects")
  237.         call makdir(Drawer"Objects")
  238.         do i=1 to obj
  239.             call METER_STEP()
  240.             call cop(object.i,Drawer"Objects",newobj.i)
  241.             if image > 1 then do
  242.                if (~open(state, object.i, 'R')) then exit
  243.                seq=0
  244.  
  245. /* Type is an array, to avoid problems with big objects */
  246.                do while eof(state) = 0
  247.             seq = seq + 1
  248.                 type.seq = readch(state,65535)
  249.                end
  250.                call close state
  251.         do t=1 to seq
  252.                l=0
  253.                l2=1
  254.                 do while (l<length(type.t))&(length(type.t)>3)
  255. /* Search for "IMG" in object, which tells us about an image file */
  256.                     l = pos("IMG",type.t,l2)
  257.                     if l ~= 0 then do
  258.                         l2 = pos(d2c(0),type.t,l+4)
  259.                         l2 = l2-l-5
  260.                         check = 0
  261.                         do s = 1 to img
  262.                         if substr(type.t,l+5,l2)=image.s then check = 1
  263.                         if substr(type.t,l+5,l2)="(none)" then check = 1
  264.                         end s
  265.                         if check=0 then do
  266.                                            img = img+1
  267.                                   image.img = substr(type.t,l+5,l2)
  268.                                           newimg.img = short(image.img,"")
  269.                         end
  270.                         l2 = l+l2
  271.                         l = l2
  272.                     end
  273.                     else l = length(type.t)
  274.                 end
  275.         end t
  276.         end
  277.            end i
  278.     end
  279.     call METER_END
  280.  
  281. /*******************************************************/
  282. /* Copy all images (and sequences) to Images directory */
  283. /*******************************************************/
  284.  
  285.     if img>0 then do
  286.         call makdir(Drawer"Images")
  287.         call METER_BEGIN(img+1,"Moving Images")
  288.         call METER_STEP
  289.         do i = 1 to img
  290.             call METER_STEP
  291. /* Handle sequences: create special dir */
  292.             if (right(image.i,11) = " (sequence)")&(image=3) then do
  293.                 name1 = CheckSeq(image.i)
  294.                 image.i = left(image.i,length(image.i)-11)
  295.                 call makdir(Drawer"Images/"||left(name1,length(name1)-1))
  296.                 call cop(image.i"#?",Drawer"Images/"name1,newimg.i)
  297.             end
  298. /* Handle image files */
  299.             else do
  300.                 call cop(image.i,Drawer"Images",newimg.i)
  301.             end
  302.          end i
  303.         call METER_END
  304.     end
  305.  
  306.  
  307.     if path = 1 then do
  308.  
  309.         name1=""
  310.  
  311. /***************************/
  312. /* Modify Scene file paths */
  313. /***************************/
  314.  
  315.         if disk>1 then do
  316.             Drawer = "Disk"
  317.             call checkdisk2(files.1)
  318.             name1="1:"
  319.         end
  320.  
  321.         l=search(filenam)
  322.         file=Drawer||name1||right(filenam,length(filenam)-l)
  323.         file=short(file,"LSC")
  324.         if (~open(state, filenam, 'R')) then break
  325.         if (~open(state2, file, 'W')) then break
  326.  
  327.         do while eof(state)=0
  328.             type = readln(state)
  329.  
  330.             if left(type,11)="LoadObject " then do
  331.                 file = delstr(type,1,11)
  332.                 l = search(file)
  333.                 i = checkdisk(file)
  334.                 type = "LoadObject " || Drawer || i || "Objects/"
  335.                     name = short(right(file,length(file)-l),"OBJ")
  336.                 type = type || name
  337.             end
  338.             if image > 1 then do
  339.                 l = pos(" ",type)
  340.                 if (left(type,l)="BGImage "),
  341.                   |(left(type,l)="FGImage "),
  342.                   |(left(type,l)="FGAlphaImage "),
  343.                   |(left(type,l)="TextureImage ") then do
  344.                     file = delstr(type,1,l)
  345.                     type = left(type,l)
  346.                     l = search(file)
  347.                     i = checkdisk(file)
  348.                     type = type || Drawer || i || "Images/"
  349.                             name = short(right(file,length(file)-l),"")
  350.                     type = type || name
  351.                 end
  352.             end
  353.         call writeln state2, type
  354.         end
  355.  
  356.         call close state
  357.         call close state2
  358.  
  359. /***************************************/
  360. /* Now modify the objects' images path */
  361. /***************************************/
  362.  
  363.         call METER_BEGIN(obj+1,"Modifying paths")
  364.         do i=1 to obj
  365.               call METER_STEP()
  366.             l = search(object.i)
  367.             t = checkdisk2(object.i)
  368.             file = Drawer || t || "Objects/"
  369.             name = short(right(object.i,length(object.i)-l),"OBJ")
  370.             file = file || name
  371.  
  372.             if (~open(state, object.i, 'R')) then break
  373.             if (~open(state2, file, 'W')) then break
  374.  
  375.         do while eof(state)=0
  376.                type = readch(state,10000)
  377.                l=0
  378.                l2=1
  379.                do while (l<length(type))&(length(type)>3)
  380.                l = pos("IMG",type,l2)
  381.                 if l ~= 0 then do
  382.                     l2 = pos(d2c(0),type,l+4)
  383.                   l2 = l2-l-5
  384.                  img = img+1
  385.                 file = substr(type,l+5,l2)
  386.                     if file~="(none)" then do
  387.                         t=search(file)
  388.                         dnum = checkdisk(file)
  389.                         say "FILE:" file
  390.                         name1 = short(CheckSeq(file),"")
  391.                         say "NAME1:" name1
  392.                         name = short(right(file,length(file)-t),"")
  393.                         say "NAME:" name
  394.                         file = Drawer || dnum || "Images/" || name1,
  395.                                || name
  396.                         file = left(type,l+3)|| d2c(length(file)+2) || file
  397.                         type = substr(type,l+l2+5)
  398.                     end
  399.                     else file = ""
  400.                   type = file || type
  401.             l2 = l+l2
  402.             l = l2
  403.                end
  404.                else l = length(type)
  405.                end
  406.        
  407.         call writech state2, type
  408.         end
  409.         call close state
  410.         call close state2
  411.         end i
  412.         call METER_END()
  413.     end
  414.     file = SHOWLIST("V",,"|")
  415. end
  416. else do
  417.     Bummer("Can't open Scene file : "filenam)
  418. end
  419. exit
  420.  
  421. /* Ask to insert new disk */
  422.  
  423. askdisk: PROCEDURE EXPOSE dnum Drawer size obj img
  424.  
  425. t=notify(3,"@Please insert a new disk in DF0:",,
  426.            "!The disk will be formatted. All Information will be lost",,
  427.            "Are you sure you want to continue?")
  428. if t=0 then exit
  429.  
  430. call METER_BEGIN(2,"Formatting disk")
  431. call METER_STEP
  432.  
  433. address command
  434. "format DRIVE" '"'Drawer'"' "NAME Disk"dnum "NOICONS >NIL:"
  435. call METER_END()
  436.  
  437. if img>0 then call makdir(Drawer||"Images")
  438. else do
  439.     if obj>0 then call makdir(Drawer||"Objects")
  440. end
  441.  
  442. /* Get info on size of all disks */
  443. "info >RAM:info.testfile "Drawer
  444.  
  445. /* Find the size of the disk we are working with */
  446. if (~open(test, "RAM:info.testfile", 'R')) then break
  447.  
  448. do i=1 to 3
  449.     text = readln(test)
  450. end i
  451.  
  452. text = readln(test)
  453. text = word(text,2)
  454. size = left(text,length(text)-1)*1000
  455.  
  456. call close test
  457.  
  458. "delete ram:info.testfile > NIL:"
  459.  
  460. return
  461.  
  462.  
  463. /* Makedir procedure */
  464.  
  465. makdir: PROCEDURE
  466.     parse arg source
  467.  
  468.     address command
  469.     if ~exists(source) then do
  470.         "makedir" '"'source'"'
  471.     end
  472. return
  473.  
  474. /* Insert disk message */
  475.  
  476. insdisk: PROCEDURE EXPOSE Drawer
  477.     parse arg num
  478.  
  479. loop:
  480.     call notify(1,"Please insert Disk" num "in any drive")
  481. /* Check that the user put the right disk in before going on */
  482.     Drives = SHOWLIST("V",,"|")
  483.     l = pos(UPPER(Drawer || num || "|"),Drives)
  484.     if l = 0 then call loop
  485. return
  486.  
  487. /* Copy procedure. Checks for disk size */
  488. Cop:
  489. /* PROCEDURE EXPOSE disk Drawer cant size dnum obj img,
  490.                       nfil files. fdisk. lha image */
  491.     parse arg source, dest, altsrc
  492.  
  493.     if comp = 2 then do
  494.             source = lharc(source)
  495.     end
  496.  
  497.     if comp = 3 then do
  498.             source = compress(source)
  499.     end
  500.  
  501.     altsrc = GetName(altsrc)
  502.  
  503.     if disk > 1 then do
  504.         add = 0
  505.         if (right(source,2) = "#?")&(image=3) then do
  506. /* Get file size for all the images in sequence
  507.  * All the images of a sequence should fit in the same device.
  508.  */
  509.             "list" source ">ram:info.testfile files quick lformat=%l"
  510.             if (~open(test, "RAM:info.testfile", 'R')) then break
  511.             do while eof(test)=0
  512.                 text = readln(test)
  513.                 if text~="" then add = add + text
  514.             end
  515.             call close test
  516.             "delete ram:info.testfile > NIL:"
  517.         end
  518.         else do
  519.             t = statef(source)
  520.             add = word(t,2)
  521.         end
  522.         if add > size then do
  523.             call notify(1,"You will not be able to fit the",,
  524.                           "current scene on floppys.  Use the Directory",,
  525.                           "Option with a backup program or try compressing",,
  526.                           "your objects before running the macro.")
  527.             exit
  528.         end
  529.         if (cant + add) > size then do
  530.                  dnum = dnum + 1
  531.                  cant = 0
  532.                  call askdisk()
  533.         end
  534.         cant = cant + add
  535.  
  536. /* Add another file to list */
  537.         nfil = nfil + 1
  538.         files.nfil = source
  539.         fdisk.nfil = dnum
  540.     end
  541.  
  542.     if ~exists(source) then do
  543.         call notify(1,"One of the files used in the",,
  544.                       "scene is no longer in the same place",,
  545.                       "or it has been deleted.  Go into Layout",,
  546.                       "and manually change the scene.")
  547.         exit
  548.     end
  549.     
  550.     name=Getname(source)
  551.  
  552. /* File exists on destination: maybe due to PC's only 8 characters
  553.     if exists(dest) then do
  554.         if rena<2 then do
  555.                call REQ_BEGIN("File "dest" already exists!")
  556.                id_rena=REQ_ADDCONTROL("",CH,"Rename"d2c(160)"it",
  557.                                       "Rename"d2c(160)"all","Cancel")
  558.                call REQ_SETVAL(id_rena,2)
  559.                call REQ_END()
  560.                rena=REQ_GETVAL(id_rena)
  561.                if rena=3 then exit 1
  562.         end
  563.         index=1
  564.         do while exists(dest||name)
  565.                 index=index+1
  566.         end
  567.         newname=left(name,8)||index
  568.         dest=dest||name
  569.     end */
  570.  
  571.     address command
  572.     "copy" '"'source'"' '"'dest'/'altsrc'"'
  573.  
  574. /* Erase ram: .lha and .Z files */
  575.     if comp > 1 then 'delete "'source'" all >NIL:'
  576. return
  577.  
  578. /* Find disk number for a file */
  579.  
  580. Checkdisk: PROCEDURE EXPOSE disk nfil files. fdisk. image
  581.     parse arg filenam
  582.  
  583.     if disk = 1 then return ""
  584.     if (right(filenam,11) = " (sequence)")&(image=3) then do
  585.         filenam = left(filenam,length(filenam)-11)||"#?"
  586.     end
  587.     do i=1 to nfil
  588.         if filenam = files.i then return fdisk.i || ":"
  589.     end i
  590.     return
  591.  
  592. /* Check disk in drive to see if it is the one where file is.
  593.  * If not, ask for disk */
  594.  
  595. Checkdisk2: PROCEDURE EXPOSE disk nfil files. fdisk. Drawer
  596.     parse arg filenam
  597.  
  598.     t = checkdisk(filenam)
  599.     if t = "" then return ""
  600.  
  601.     t=left(t,1)
  602.     Drives = SHOWLIST("V",,"|")
  603.     l = pos(UPPER(Drawer || t || "|"),Drives)
  604.     if l = 0 then call insdisk(t)
  605.     t = t || ":"
  606.     
  607. return t
  608.  
  609. CheckSeq: PROCEDURE EXPOSE image
  610.     parse arg filenam
  611.  
  612.         test = ""
  613.         if (right(filenam,11) = " (sequence)")&(image=3) then do
  614.             filenam = left(filenam,length(filenam)-11)
  615.             l = length(filenam) - search(filenam)
  616.             test = right(filenam,l)||"/"
  617.         end
  618. return test
  619.  
  620. Search: PROCEDURE
  621.     parse arg filenam
  622.         i = lastpos("/",filenam)
  623.         l = lastpos(":",filenam)
  624.         if l>i then i=l
  625. return i
  626.  
  627. /* Strip extensions and get name of file only */
  628. GetName: PROCEDURE
  629. parse arg name
  630.     l = search(name)
  631.     if n ~= 0 then do
  632.         name=right(name,length(name)-l)
  633.         say name
  634.     end  
  635. return name
  636.  
  637. /* Compress files to ram: before copying them */
  638.  
  639. Lharc: PROCEDURE
  640.     parse arg source
  641.  
  642.     l = search(source)
  643.     file = "ram:" || right(source,length(source)-l)
  644.  
  645.     'LHA -x a "'file||'.lha"' '"'source'" >NIL:'
  646.     'rename "'file||'.lha"' '"'file'"'
  647.  
  648. return file
  649.  
  650. compress: PROCEDURE EXPOSE short repl
  651.     parse arg source
  652.  
  653.     l = search(source)
  654.     l2 = short
  655.     short = 1
  656.     file = short("ram:" || right(source,length(source)-l),"")
  657.     short = l2
  658.     
  659.     'copy "'source'" "'file'"'
  660.     'compress.b16 "'file'"'
  661.     file = file || ".Z"
  662.     say file
  663.  
  664. return file
  665.  
  666. Short: PROCEDURE EXPOSE short repl
  667.     parse arg file, ext
  668.  
  669.     l = search(file)
  670.  
  671.     l2 = 8
  672.     if (l + 8) > length(file) then l2 = length(file) - l
  673.  
  674.     if repl = 1 then file = translate(file,"_-"," .")
  675.  
  676.     if ext ~= "" then ext = "." || ext
  677.  
  678.     if short = 1 then file = left(file,l) || substr(file,l+1,l2) || ext
  679.  
  680. return file
  681.  
  682. Bummer:
  683.   parse arg etxt
  684.   t=Notify(1,'!Rexx Script Error','@'ETxt)
  685.   exit
  686.  
  687. syntax:
  688. error:
  689.   call end_all
  690.   t=Notify(1,'!Rexx Script Error','@'ErrorText(rc),'Line 'SIGL)
  691.   exit
  692.  
  693.